package com.vteba.utils.id;

import java.util.concurrent.atomic.AtomicInteger;

import com.vteba.utils.common.PropUtils;
import com.vteba.utils.date.JodaTimeUtils;

/**
 * 主键生成器，yyyyMMddHHmmssSSS + 循环自增数字。
 * @author yinlei
 * @date 2014年10月15日 下午3:28:50
 */
public class Ids {
	private static String YMD = "yyyyMMddHHmmssSSS";
	private static int ID_START = 1000000;
	private static int SAFETY_VALVE = 8000000;
	private static String PREFIX;
	
	private static volatile AtomicInteger INTEGER = new AtomicInteger(1);
	
	static {
		// 主键起始值
		int idStart = PropUtils.getInt("id.start", ID_START);
		INTEGER.set(idStart);
		ID_START = idStart;
		
		// 安全阀
		int safetyValve = PropUtils.getInt("id.safety.valve", SAFETY_VALVE);
		SAFETY_VALVE = safetyValve;
		
		// 日期格式
		String ymd = PropUtils.get("id.format", YMD);
		YMD = ymd;
		
		// 前缀
		String prefix = PropUtils.get("id.prefix");
		PREFIX = prefix;
	}
	
	/**
	 * 获取固定长度的id。格式是yyyyMMddHHmmssSSS + 7位循环自增数字.<br>
	 * 1000000-8000000(可能大于该值).预留200W，尽量确保不会超过7位数字。
	 * @return id字符串
	 */
	public static String get() {
		String date = JodaTimeUtils.format(YMD);
		int sequence = INTEGER.getAndIncrement();
		if (sequence > SAFETY_VALVE) { // 这里应该怎么优化
			INTEGER.set(ID_START);
		}
		if (PREFIX != null) {
			return PREFIX + date + sequence;
		}
		return date + sequence;
	}
	
	/**
	 * 获取可变长度的id。格式是yyyyMMddHHmmssSSS + 自增数字.<br>
	 * 1-Integer.MAX_VALUE = 2147483647(可能大于该值)
	 * @return id字符串
	 */
	public static String getId() {
		String date = JodaTimeUtils.format(YMD);
		int sequence = INTEGER.getAndIncrement();
		if (sequence > Integer.MAX_VALUE) { // 这里应该怎么优化
			INTEGER.set(1);
		}
		if (PREFIX != null) {
			return PREFIX + date + sequence;
		}
		return date + sequence;
	}
}
